package xyz.zhno.mall.common.web.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import xyz.zhno.mall.common.core.enums.ErrorCodeEnum;
import xyz.zhno.mall.common.core.exception.APIException;

import java.util.Map;

/**
 * JSON工具类
 * @author zh_o
 */
public class JSONUtils {

    private static final ObjectMapper JSON;

    static {
        JSON = new ObjectMapper();
        // 忽略json中在对象不存在对应属性
        JSON.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 忽略空bean转json错误
        JSON.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 解决序列化LocalDateTime报错
        JSON.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        JSON.registerModule(new JavaTimeModule());
    }

    /**
     * 转换为json串
     * @param bean 对象
     * @return json串
     */
    public static String toJsonStr(Object bean) {
        try {
            return JSON.writeValueAsString(bean);
        } catch (JsonProcessingException e) {
            throw new APIException(ErrorCodeEnum.JSON_ERROR);
        }
    }

    /**
     * 转换为字节数组
     * @param bean 对象
     * @return 字节数组
     */
    public static byte[] toJsonByte(Object bean) {
        try {
            return JSON.writeValueAsBytes(bean);
        } catch (JsonProcessingException e) {
            throw new APIException(ErrorCodeEnum.JSON_ERROR);
        }
    }

    /**
     * 转换为对象
     * @param jsonStr json串
     * @param beanType 对象类型
     * @return 对象
     */
    public static <T> T toBean(String jsonStr, Class<T> beanType) {
        try {
            return JSON.readValue(jsonStr, beanType);
        } catch (JsonProcessingException e) {
            throw new APIException(ErrorCodeEnum.JSON_ERROR);
        }
    }

    /**
     * 对象转换为指定类型bean
     * @param obj 对象
     * @param beanType bean类型
     * @return 转化后对象
     */
    public static <T> T toBean(Object obj, Class<T> beanType) {
        return toBean(toJsonStr(obj), beanType);
    }

    /**
     * map转换为对象
     * @param map map
     * @param beanType 对象类型
     * @return bean
     */
    public static <T> T toBean(Map<?, ?> map, Class<T> beanType) {
        return toBean(toJsonStr(map), beanType);
    }

    /**
     * 转换为map
     * @param jsonStr json串
     * @param mapType map类型
     * @param kType key类型
     * @param vType value类型
     * @return map
     */
    public static <T extends Map<?, ?>, K, V> Map<K, V> toMap(String jsonStr, Class<T> mapType, Class<K> kType, Class<V> vType) {
        try {
            return JSON.readValue(jsonStr, JSON.getTypeFactory().constructMapType(mapType, kType, vType));
        } catch (JsonProcessingException e) {
            throw new APIException(ErrorCodeEnum.JSON_ERROR);
        }
    }

    /**
     * 对象转换为map
     * @param obj 对象
     * @param mapType map类型
     * @param kType key类型
     * @param vType value类型
     * @return map
     */
    public static <T extends Map<?, ?>, K, V> Map<K, V> toMap(Object obj, Class<T> mapType, Class<K> kType, Class<V> vType) {
        return toMap(toJsonStr(obj), mapType, kType, vType);
    }

}
